# !/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/7/2 8:05 下午
# @Author  : 白辉东
# @Mail    : masterbai2018@outlook.com
# @File    : run.py
# @Software: PyCharm

import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import QTimer, pyqtSignal
from main import Ui_Form
from SerialReader import get_serial, get_serial_com
import numpy as np
import pyqtgraph as pg
from threading import Thread
import re

data_volt = np.empty(100)
data_power = np.empty(100)
data_time = np.empty(100, dtype=object)
ptr = 0

t = None


class MyWindow(QWidget):
    power_signal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.pattern = re.compile(r'\d+')
        self.data_mem = []
        self.data_power = []
        self.timer_1 = QTimer(self)
        self.timer_2 = QTimer(self)

        self.curve_volt = self.ui.graphicsView_volt.plot()
        self.curve_mem = self.ui.graphicsView_mem.plot()
        self.curve_power = self.ui.graphicsView_power.plot()

        # self.vLine = pg.InfiniteLine(angle=90, movable=False)
        # self.hLine = pg.InfiniteLine(angle=0, movable=False)
        self.label_1 = pg.LabelItem(justify='right')
        self.ui.graphicsView_volt.addItem(self.label_1)
        # self.ui.graphicsView_volt.addItem(self.vLine, ignoreBounds=True)
        # self.ui.graphicsView_volt.addItem(self.hLine, ignoreBounds=True)
        self.ui.graphicsView_volt.showGrid(x=True, y=True)
        # self.ui.graphicsView_volt.setDownsampling(mode='peak')
        # self.ui.graphicsView_volt.setClipToView(True)
        self.ui.graphicsView_volt.setTitle('电压数据统计（单位：vlot）')

        self.ui.graphicsView_mem.showGrid(x=True, y=True)
        self.ui.graphicsView_mem.setDownsampling(mode='peak')
        self.ui.graphicsView_mem.setClipToView(True)
        self.ui.graphicsView_mem.setTitle('内存数据统计（单位：%）')

        self.ui.graphicsView_power.showGrid(x=True, y=True)
        self.ui.graphicsView_power.setDownsampling(mode='peak')
        self.ui.graphicsView_power.setClipToView(True)
        self.ui.graphicsView_power.setTitle('电量百分比数据统计（单位：%）')

        # 设置Y轴范围
        self.ui.graphicsView_power.setYRange(max=100, min=0)
        self.ui.graphicsView_mem.setYRange(max=100, min=0)
        self.ui.graphicsView_volt.setYRange(max=5, min=3)

        self.init()

    def init(self):
        port = get_serial_com()
        ser = get_serial(port)
        # 电量信号
        self.power_signal.connect(self.update_power)
        # 开始触发
        self.ui.pushButton.clicked.connect(lambda: self.read_serial(ser))

        # self.curve_volt.scene().sigMouseMoved.connect(self.mouse_moved)

        # 查询内存
        self.timer_1.timeout.connect(lambda: self.execute_mem(ser))
        # 每隔15秒执行一次函数
        self.timer_1.start(10000)

        # # 查询内存
        # self.timer_2.timeout.connect(lambda: self.execute_cpu(ser))
        # # 每隔20秒执行一次函数
        # self.timer_2.start(20000)

    def update_power(self, logs):
        result = self.pattern.findall(logs)
        volt = int(result[-2])
        power = int(result[-1])
        time_stamp = f'{result[3]}:{result[4]}'
        global data_volt, data_power, data_time, ptr
        data_volt[ptr] = format(volt / 1000, f'.5')
        print(data_volt[ptr])
        data_power[ptr] = power
        data_time[ptr] = time_stamp
        ptr += 1
        if ptr >= data_volt.shape[0]:
            tmp_1 = data_volt
            data_volt = np.empty(data_volt.shape[0] * 2)
            data_volt[:tmp_1.shape[0]] = tmp_1

            tmp_2 = data_power
            data_power = np.empty(data_power.shape[0] * 2)
            data_power[:tmp_2.shape[0]] = tmp_2

            tmp_3 = data_time
            data_time = np.empty(data_time.shape[0] * 2, dtype=object)
            data_time[:tmp_3.shape[0]] = tmp_3

        self.curve_volt.setData(data_volt[:ptr], pen='g')
        self.curve_power.setData(data_power[:ptr], pen='g')

    # 读取串口数据
    def read_serial(self, ser):
        def task():
            while getattr(t, "open", True):
                line = ser.readline().strip()
                log = line.replace(b'\\\\x', b'%').decode("UTF-8", "ignore")
                print(log)
                if 'keyuser app_bat_get_volt()=' in log:
                    self.power_signal.emit(log)

        global t
        t = Thread(target=task)
        t.start()

    @staticmethod
    def execute_mem(ser):
        cmd = 'free\n'
        ser.write(cmd.encode())

    @staticmethod
    def execute_cpu(ser):
        cmd = 'ps\n'
        ser.write(cmd.encode())

    def mouse_moved(self, pos):
        pos = self.ui.graphicsView_volt.mapFromScene(pos)
        print(type(self.curve_volt))

        if self.ui.graphicsView_volt.sceneBoundingRect().contains(pos):
            mouse_point = self.curve_volt.vb.mapSceneToView(pos)
            index = int(mouse_point.x())
            if 0 < index < len(data_volt):
                self.label_1.setText(
                    "<span style='font-size: 12pt'>x=%0.1f,   <span style='color: red'>y1=%0.1f</span>" % (
                        mouse_point.x(), data_volt[index]))
            self.vLine.setPos(mouse_point.x())
            self.hLine.setPos(mouse_point.y())

    # TODO 完全退出时进行线程清理
    def closeEvent(self, event) -> None:
        global t
        t.open = False


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec())
